/*
 * maz_drv_i2c.c
 *
 *  Created on: 2020年7月17日
 *      Author: ChenBlue
 */

#include "maz_drv.h"

/**
 * "dlvl" variables must be defined if debug message is to be printed through the dlog/dmsg, and "dlvl" must be declared static
 */
static int dlvl = DINF;

MAZDRV_I2C_CTRL __g_mazdrv_i2c_ctrl[MAZDRV_E_I2C_MAX] =
{
    [MAZDRV_E_I2C1] =
    {
        .use            = MAZDRV_E_I2C_USE_ENABLE,
        .cfg.iomap      = MAZDRV_E_I2C1_IOMAP2_PB8_PB9,
        .cfg.conf       =
        {
            .Instance   = I2C1,
            .Init       =
            {
                .ClockSpeed         = 100000,
                .DutyCycle          = I2C_DUTYCYCLE_2,
                .OwnAddress1        = 0,
                .AddressingMode     = I2C_ADDRESSINGMODE_7BIT,
                .DualAddressMode    = I2C_DUALADDRESS_DISABLE,
                .OwnAddress2        = 0,
                .GeneralCallMode    = I2C_GENERALCALL_DISABLE,
                .NoStretchMode      = I2C_NOSTRETCH_DISABLE,
            },
        },
    },
    [MAZDRV_E_I2C2] =
    {
        .use = MAZDRV_E_I2C_USE_DISABLE,
    },
    [MAZDRV_E_I2C3] =
    {
        .use = MAZDRV_E_I2C_USE_DISABLE,
    },
};

/* Internal Interface Functions */
int MAZ_Drv_i2c_clk_enable(MAZDRV_E_I2C index);
int MAZ_Drv_i2c_ioremap(MAZDRV_E_I2C index);
int MAZ_Drv_i2c_config(MAZDRV_E_I2C index);
int MAZ_Drv_i2c_debugcmd_rigister(void);

int MAZ_Drv_i2c_init(void)
{
    MAZDRV_E_I2C index = 0;
    MAZDRV_I2C_CTRL *ctrl = NULL;

    for (index = MAZDRV_E_I2C1; index < MAZDRV_E_I2C_MAX; index++)
    {
        ctrl = &__g_mazdrv_i2c_ctrl[index];

        if (MAZDRV_E_I2C_USE_ENABLE != ctrl->use)
        {
            continue;
        }

        MAZ_Drv_i2c_clk_enable(index);
        MAZ_Drv_i2c_ioremap(index);
        MAZ_Drv_i2c_config(index);
    }

    MAZ_Drv_i2c_debugcmd_rigister();

    return MAZRET_OK;
}

int MAZ_Drv_i2c_clk_enable(MAZDRV_E_I2C index)
{
    if (index < MAZDRV_E_I2C1 || index >= MAZDRV_E_I2C_MAX)
    {
        return MAZRET_EINVAL;
    }

    switch (index)
    {
    case MAZDRV_E_I2C1:
        __HAL_RCC_I2C1_CLK_ENABLE();
        break;
    case MAZDRV_E_I2C2:
        __HAL_RCC_I2C2_CLK_ENABLE();
        break;
    case MAZDRV_E_I2C3:
        __HAL_RCC_I2C3_CLK_ENABLE();
        break;
    case MAZDRV_E_I2C_MAX:
        // do nothing, for remove warning
        break;
    }

    return MAZRET_OK;
}

int MAZ_Drv_i2c_ioremap(MAZDRV_E_I2C index)
{
    MAZDRV_I2C_CTRL *ctrl = NULL;
    MAZDRV_E_I2C_IOMAP map = 0;
    GPIO_InitTypeDef GPIO_InitStruct = { 0 };

    if (index < MAZDRV_E_I2C1 || index >= MAZDRV_E_I2C_MAX)
    {
        return MAZRET_EINVAL;
    }

    ctrl = &__g_mazdrv_i2c_ctrl[index];
    map = ctrl->cfg.iomap;

    if (map < MAZDRV_E_I2C1_IOMAP1_PB6_PB7 || map > MAZDRV_E_I2C3_IOMAP1_PA8_PB4)
    {
        return MAZRET_EINVAL;
    }

    switch (map)
    {
    case MAZDRV_E_I2C1_IOMAP1_PB6_PB7:
        __HAL_RCC_GPIOB_CLK_ENABLE();

        GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
        break;

    case MAZDRV_E_I2C1_IOMAP2_PB8_PB9:
        __HAL_RCC_GPIOB_CLK_ENABLE();

        GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
        break;

    case MAZDRV_E_I2C2_IOMAP1_PB10_PB3:
        __HAL_RCC_GPIOA_CLK_ENABLE();

        GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_3;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
        break;

    case MAZDRV_E_I2C3_IOMAP1_PA8_PB4:
        __HAL_RCC_GPIOA_CLK_ENABLE();
        __HAL_RCC_GPIOB_CLK_ENABLE();

        GPIO_InitStruct.Pin = GPIO_PIN_8;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF4_I2C3;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

        GPIO_InitStruct.Pin = GPIO_PIN_4;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
        break;
    }

    return MAZRET_OK;
}

int MAZ_Drv_i2c_config(MAZDRV_E_I2C index)
{
    int ret = 0;
    MAZDRV_I2C_CTRL *ctrl = NULL;

    if (index < MAZDRV_E_I2C1 || index >= MAZDRV_E_I2C_MAX)
    {
        return MAZRET_EINVAL;
    }

    ctrl = &__g_mazdrv_i2c_ctrl[index];

    ret = HAL_I2C_Init(&ctrl->cfg.conf);
    if (ret != HAL_OK)
    {
        return MAZRET_NG;
    }

    return MAZRET_OK;
}

int MAZ_DBGCMD_i2c_detect(void *cmd, char *param)
{
    int ret = 0;                        // 返回值
    int flag = -1;                      // 参数不合法标志
    int index = -1;                     // 解析到的I2C引擎索引
    char *str;                          // 暂存解析参数得到的目标字符串
    char *tmp;                          // 暂存解析参数剩余的字符串
    uint8_t i = 0;                      // 循环变量
    uint8_t dev = 0;                    // 循环变量, 设备地址
    MAZDRV_I2C_CTRL *ctrl = NULL;

    str = strtok_r(param, " ", &tmp);
    if (NULL != str)
    {
        index = atoi(str);
        flag = 0;
    }

    /* Sub command without parameter  */
    if (flag)
    {
        for (index = MAZDRV_E_I2C1; index < MAZDRV_E_I2C_MAX; index++)
        {
            ctrl = &__g_mazdrv_i2c_ctrl[index];
            if (MAZDRV_E_I2C_USE_ENABLE == ctrl->use)
            {
                printf("i2c%u       stm32 i2c engine       hardware i2c\r\n", index);
            }
        }
        return MAZRET_OK;
    }

    dmsg(DBUG, "bus = %d\r\n", index);

    if (index < MAZDRV_E_I2C1 || index >= MAZDRV_E_I2C_MAX)
    {
        printf("err: i2c%d bus not exist.\r\n", index);
        return MAZRET_OK;
    }

    ctrl = &__g_mazdrv_i2c_ctrl[index];
    if (MAZDRV_E_I2C_USE_ENABLE != ctrl->use)
    {
        printf("err: i2c%d bus not enable.\r\n", index);
        return MAZRET_OK;
    }

    printf("   ");
    for (i = 0; i < 16; i++)
    {
        printf(" %2x", i);
    }
    fflush(stdout);

    for (dev = 0; dev < 128; dev++)
    {
        if ((dev & 0xf) == 0)
        {
            printf("\r\n%02x:", (dev >> 4) << 4);
        }

        ret = HAL_I2C_IsDeviceReady(&ctrl->cfg.conf, dev << 1, 1, 5);
        switch (ret)
        {
        case HAL_BUSY:
            printf(" UU");
            break;
        case HAL_ERROR:
            printf(" --");
            break;
        case HAL_TIMEOUT:
            printf(" TT");
            break;
        case HAL_OK:
            printf(" %02x", dev);
            break;
        }
        fflush(stdout);
    }

    printf("\r\n");

    return MAZRET_OK;
}

int MAZ_DBGCMD_i2c_get(void *cmd, char *param)
{
    int ret = 0;                        // 返回值
    int flag = -1;                      // 参数不合法标志
    int index = -1;                     // 解析到的I2C引擎索引
    char *str;                          // 暂存解析参数得到的目标字符串
    char *tmp;                          // 暂存解析参数剩余的字符串
    uint32_t dev = 0;                   // 设备地址
    uint32_t reg = 0;                   // 寄存器地址
    uint8_t val = 0;                    // 寄存器值
    MAZDRV_I2C_CTRL *ctrl = NULL;

    str = strtok_r(param, " ", &tmp);
    if (NULL != str)
    {
        index = atoi(str);
        str = strtok_r(NULL, " ", &tmp);
        if (NULL != str)
        {
            dev = atoh(str);
            str = strtok_r(NULL, " ", &tmp);
            if (NULL != str)
            {
                reg = atoh(str);
                flag = 0;
            }
        }
    }

    /* Sub command without parameter  */
    if (flag)
    {
        printf("usage: i2c get <bus> <dev> <reg>\r\n");
        printf("   eg: i2c get 0 0x50 0x13\r\n");
        return MAZRET_OK;
    }

    dmsg(DBUG, "bus/dev/reg = %d/0x%02lx/0x%02lx\r\n", index, dev, reg);

    /* Sub command with parameter */
    if (index < MAZDRV_E_I2C1 || index >= MAZDRV_E_I2C_MAX)
    {
        printf("err: i2c%d bus not exist.\r\n", index);
        return MAZRET_OK;
    }

    ctrl = &__g_mazdrv_i2c_ctrl[index];
    if (MAZDRV_E_I2C_USE_ENABLE != ctrl->use)
    {
        printf("err: i2c%d bus not enable.\r\n", index);
        return MAZRET_OK;
    }

    ret = HAL_I2C_Mem_Read(&ctrl->cfg.conf, (dev << 1) + 1, reg, I2C_MEMADD_SIZE_8BIT, &val, 1, 1000);
    switch (ret)
    {
    case HAL_BUSY:
        printf("err: i2c%d bus busy\r\n", index);
        break;
    case HAL_ERROR:
        printf("err: i2c%d bus error\r\n", index);
        break;
    case HAL_TIMEOUT:
        printf("err: i2c%d bus timeout\r\n", index);
        break;
    case HAL_OK:
        printf("%02x\r\n", val);
        break;
    }
    fflush(stdout);

    return MAZRET_OK;
}

int MAZ_DBGCMD_i2c_set(void *cmd, char *param)
{
    int ret = 0;                        // 返回值
    int flag = -1;                      // 参数不合法标志
    int index = -1;                     // 解析到的I2C引擎索引
    char *str;                          // 暂存解析参数得到的目标字符串
    char *tmp;                          // 暂存解析参数剩余的字符串
    uint8_t dev = 0;                    // 设备地址
    uint8_t reg = 0;                    // 寄存器地址
    uint8_t val = 0;                    // 寄存器值
    MAZDRV_I2C_CTRL *ctrl = NULL;

    str = strtok_r(param, " ", &tmp);
    if (NULL != str)
    {
        index = atoi(str);
        str = strtok_r(NULL, " ", &tmp);
        if (NULL != str)
        {
            dev = atoh(str);
            str = strtok_r(NULL, " ", &tmp);
            if (NULL != str)
            {
                reg = atoh(str);
                str = strtok_r(NULL, " ", &tmp);
                if (NULL != str)
                {
                    val = atoh(str);
                    flag = 0;
                }
            }
        }
    }

    /* Sub command without parameter  */
    if (flag)
    {
        printf("usage: i2c set <bus> <dev> <reg> <val>\r\n");
        printf("   eg: i2c set 0 0x50 0x13 0x23\r\n");
        return MAZRET_OK;
    }

    dmsg(DBUG, "bus/dev/reg/val = %d/0x%02lx/0x%02lx/0x%02lx\r\n", index, (uint32_t )dev, (uint32_t )reg,
         (uint32_t )val);

    /* Sub command with parameter */
    if (index < MAZDRV_E_I2C1 || index >= MAZDRV_E_I2C_MAX)
    {
        printf("err: i2c%d bus not exist.\r\n", index);
        return MAZRET_OK;
    }

    ctrl = &__g_mazdrv_i2c_ctrl[index];
    if (MAZDRV_E_I2C_USE_ENABLE != ctrl->use)
    {
        printf("err: i2c%d bus not enable.\r\n", index);
        return MAZRET_OK;
    }

    ret = HAL_I2C_Mem_Write(&ctrl->cfg.conf, (dev << 1) + 1, reg, I2C_MEMADD_SIZE_8BIT, &val, 1, 1000);
    switch (ret)
    {
    case HAL_BUSY:
        printf("err: i2c%d bus busy\r\n", index);
        break;
    case HAL_ERROR:
        printf("err: i2c%d bus error\r\n", index);
        break;
    case HAL_TIMEOUT:
        printf("err: i2c%d bus timeout\r\n", index);
        break;
    }
    fflush(stdout);

    return MAZRET_OK;
}

int MAZ_DBGCMD_i2c_dump(void *cmd, char *param)
{
    int ret = 0;                        // 返回值
    int flag = -1;                      // 参数不合法标志
    int index = -1;                     // 解析到的I2C引擎索引
    char *str;                          // 暂存解析参数得到的目标字符串
    char *tmp;                          // 暂存解析参数剩余的字符串
    char ch;
    uint8_t dev = 0;                    // 设备地址
    uint8_t val = 0;                    // 寄存器值
    uint8_t i = 0;                      // 循环变量
    uint8_t j = 0;                      // 循环变量
    uint8_t col = 16;                   // 每行显示多少列数据
    uint8_t row = 16;                   // 总共显示多少行
    uint8_t buff[16];
    MAZDRV_I2C_CTRL *ctrl = NULL;

    str = strtok_r(param, " ", &tmp);
    if (NULL != str)
    {
        index = atoi(str);
        str = strtok_r(NULL, " ", &tmp);
        if (NULL != str)
        {
            dev = atoh(str);
            flag = 0;
        }
    }

    /* Sub command without parameter  */
    if (flag)
    {
        printf("usage: i2c dump <bus> <dev>\r\n");
        printf("   eg: i2c dump 0 0x50\r\n");
        return MAZRET_OK;
    }

    dmsg(DBUG, "bus/dev = %d/0x%02lx\r\n", index, (uint32_t )dev);

    /* Sub command with parameter */
    if (index < MAZDRV_E_I2C1 || index >= MAZDRV_E_I2C_MAX)
    {
        printf("err: i2c%d bus not exist.\r\n", index);
        return MAZRET_OK;
    }

    ctrl = &__g_mazdrv_i2c_ctrl[index];
    if (MAZDRV_E_I2C_USE_ENABLE != ctrl->use)
    {
        printf("err: i2c%d bus not enable.\r\n", index);
        return MAZRET_OK;
    }

    printf("   ");
    for (i = 0; i < col; i++)
    {
        printf(" %2x", i);
    }
    printf("    ");
    for (i = 0; i < col; i++)
    {
        printf("%x", i);
    }

    for (i = 0; i < row; i++)
    {
        printf("\r\n%02x:", i * col);
        for (j = 0; j < col; j++)
        {
            ret = HAL_I2C_Mem_Read(&ctrl->cfg.conf, (dev << 1) + 1, i * col + j, I2C_MEMADD_SIZE_8BIT, &val, 1, 1000);
            switch (ret)
            {
            case HAL_BUSY:
                printf(" UU");
                break;
            case HAL_ERROR:
                printf(" ER");
                break;
            case HAL_TIMEOUT:
                printf(" TT");
                break;
            case HAL_OK:
                buff[j] = val;
                printf(" %02x", val);
                fflush(stdout);
                break;
            }
        }

        printf("    ");
        for (j = 0; j < col; j++)
        {
            ch = buff[j];

            if ('\t' == ch)
                ch = '>';
            else if ('\b' == ch)
                ch = '<';
            else if ('\r' == ch)
                ch = '\\';
            else if ('\n' == ch)
                ch = '\\';
            else if (0x03 == ch)
                ch = '^';
            else if (ch < 32 || ch >= 127)
                ch = '.';

            printf("%c", ch);
            fflush(stdout);
        }
    }
    printf("\r\n");

    return MAZRET_OK;
}

int MAZ_DBGCMD_i2c_engine(void *cmd, char *param)
{
    int flag = -1;                      // 参数不合法标志
    int index = -1;                     // 解析到的I2C引擎索引
    char *str;                          // 暂存解析参数得到的目标字符串
    char *tmp;                          // 暂存解析参数剩余的字符串
    MAZDRV_I2C_CTRL *ctrl = NULL;

    str = strtok_r(param, " ", &tmp);
    if (NULL != str)
    {
        index = atoi(str);
        flag = 0;
    }

    /* Sub command without parameter  */
    if (flag)
    {
        printf("usage: i2c engine <bus>\r\n");
        printf("   eg: i2c engine 0\r\n");
        return MAZRET_OK;
    }

    dmsg(DBUG, "bus = %d\r\n", index);

    /* Sub command with parameter */
    if (index < MAZDRV_E_I2C1 || index >= MAZDRV_E_I2C_MAX)
    {
        printf("err: i2c%d bus not exist.\r\n", index);
        return MAZRET_OK;
    }

    ctrl = &__g_mazdrv_i2c_ctrl[index];
    printf("[I2C%d]CR1   = 0x%08lx\r\n", index, ctrl->cfg.conf.Instance->CR1);
    printf("[I2C%d]CR2   = 0x%08lx\r\n", index, ctrl->cfg.conf.Instance->CR2);
    printf("[I2C%d]OAR1  = 0x%08lx\r\n", index, ctrl->cfg.conf.Instance->OAR1);
    printf("[I2C%d]OAR2  = 0x%08lx\r\n", index, ctrl->cfg.conf.Instance->OAR2);
    printf("[I2C%d]DR    = 0x%08lx\r\n", index, ctrl->cfg.conf.Instance->DR);
    printf("[I2C%d]SR1   = 0x%08lx\r\n", index, ctrl->cfg.conf.Instance->SR1);
    printf("[I2C%d]SR2   = 0x%08lx\r\n", index, ctrl->cfg.conf.Instance->SR2);
    printf("[I2C%d]CCR   = 0x%08lx\r\n", index, ctrl->cfg.conf.Instance->CCR);
    printf("[I2C%d]TRISE = 0x%08lx\r\n", index, ctrl->cfg.conf.Instance->TRISE);
    printf("[I2C%d]FLTR  = 0x%08lx\r\n", index, ctrl->cfg.conf.Instance->FLTR);

    return MAZRET_OK;
}

int MAZ_DBGCMD_i2c_dlvl(void *cmd, char *param)
{
    int flag = -1;                      // 参数不合法标志
    int level = -1;                     // 解析到的打印等级配置
    char *str;                          // 暂存解析参数得到的目标字符串
    char *tmp;                          // 暂存解析参数剩余的字符串

    str = strtok_r(param, " ", &tmp);
    if (NULL != str)
    {
        level = atoi(str);
        flag = 0;
    }

    /* Sub command without parameter  */
    if (flag)
    {
        printf("%s(%d)\r\n", \
                   (DERR == dlvl) ?  "DERR" : \
                   (DWAN == dlvl) ?  "DWAN" : \
                   (DINF == dlvl) ?  "DINF" : \
                   (DBUG == dlvl) ?  "DBUG" : "DIGN", dlvl);
        return MAZRET_OK;
    }

    if (level < DERR || level > DIGN)
    {
        printf("err: level %d out of range\r\n", level);
        printf("level:\r\n");
        printf("   DERR 0   error\r\n");
        printf("   DWAN 1   warning\r\n");
        printf("   DINF 2   information\r\n");
        printf("   DBUG 3   debug\r\n");
        printf("   DIGN 4   ignore\r\n");
        return MAZRET_OK;
    }

    dlvl = level;
    printf("dlvl = %s(%d)\r\n", \
           (DERR == dlvl) ?  "DERR" : \
           (DWAN == dlvl) ?  "DWAN" : \
           (DINF == dlvl) ?  "DINF" : \
           (DBUG == dlvl) ?  "DBUG" : "DIGN", dlvl);

    return MAZRET_OK;
}

int MAZ_DBGCMD_i2c_config(void *cmd, char *param)
{
    int index = 0;                      // 循环变量
    MAZDRV_I2C_CTRL *ctrl = NULL;

    printf("%-8s %-8s %-8s %-8s %-8s\r\n", "BUS", "USE", "SCL&SDA", "SPEED", "MODE");

    for (index = MAZDRV_E_I2C1; index < MAZDRV_E_I2C_MAX; index++)
    {
        ctrl = &__g_mazdrv_i2c_ctrl[index];
        if (MAZDRV_E_I2C_USE_ENABLE != ctrl->use)
        {
            printf("%-8d %-8s %-8s %-8s %-8s\r\n", index, "DISABLE", "-", "-", "-");
            continue;
        }

        printf("%-8d %-8s %-8s %-8ld %-8s\r\n", \
               index, \
               "ENABLE", \
               (MAZDRV_E_I2C1_IOMAP1_PB6_PB7 == ctrl->cfg.iomap) ? "PB6&PB7" : "PB8&PB9", \
               ctrl->cfg.conf.Init.ClockSpeed, \
               (I2C_ADDRESSINGMODE_7BIT == ctrl->cfg.conf.Init.AddressingMode) ? "7BIT" : "10BIT");
    }

    return MAZRET_OK;
}

static MAZCPNT_MAIN_CMD mcmd_i2c        = { "i2c",          "i2c engine debug command." };
static MAZCPNT_SUB_CMD  scmd_i2c_detect = { "detect",       "i2c detect [bus].",                MAZ_DBGCMD_i2c_detect };
static MAZCPNT_SUB_CMD  scmd_i2c_get    = { "get",          "i2c get <bus> <dev> <reg>.",       MAZ_DBGCMD_i2c_get };
static MAZCPNT_SUB_CMD  scmd_i2c_set    = { "set",          "i2c set <bus> <dev> <reg> <val>.", MAZ_DBGCMD_i2c_set };
static MAZCPNT_SUB_CMD  scmd_i2c_dump   = { "dump",         "i2c dump <bus> <dev>.",            MAZ_DBGCMD_i2c_dump };
static MAZCPNT_SUB_CMD  scmd_i2c_engine = { "engine",       "i2c engine <bus>.",                MAZ_DBGCMD_i2c_engine };
static MAZCPNT_SUB_CMD  scmd_i2c_dlvl   = { "dlvl",         "i2c dlvl [level].",                MAZ_DBGCMD_i2c_dlvl };
static MAZCPNT_SUB_CMD  scmd_i2c_config = { "config",       "i2c config <bus>.",                MAZ_DBGCMD_i2c_config };

int MAZ_Drv_i2c_debugcmd_rigister(void)
{
    MAZ_CPNT_debugcmd_mcmd_register(&mcmd_i2c);
    MAZ_CPNT_debugcmd_scmd_register(&mcmd_i2c, &scmd_i2c_detect);
    MAZ_CPNT_debugcmd_scmd_register(&mcmd_i2c, &scmd_i2c_get);
    MAZ_CPNT_debugcmd_scmd_register(&mcmd_i2c, &scmd_i2c_set);
    MAZ_CPNT_debugcmd_scmd_register(&mcmd_i2c, &scmd_i2c_dump);
    MAZ_CPNT_debugcmd_scmd_register(&mcmd_i2c, &scmd_i2c_engine);
    MAZ_CPNT_debugcmd_scmd_register(&mcmd_i2c, &scmd_i2c_dlvl);
    MAZ_CPNT_debugcmd_scmd_register(&mcmd_i2c, &scmd_i2c_config);

    return MAZRET_OK;
}
